package com.surenpi.jenkins.client.credential;

import com.surenpi.jenkins.client.BaseManager;
import com.surenpi.jenkins.client.BaseModel;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

public class Credentials extends BaseManager {
   public static final String V1URL = "/credential-store/domain/_";
   public static final String V2URL = "/credentials/store/system/domain/_";
   private String baseUrl = "/credentials/store/system/domain/_";
   private boolean isVersion1 = false;

   public Credentials() {
   }

   public Credentials(String baseUrl) {
      this.baseUrl = baseUrl;
      if ("/credential-store/domain/_".equals(baseUrl)) {
         this.isVersion1 = true;
      }

   }

   public void create(Credential credential) throws IOException {
      this.create(credential, this.isCrumb());
   }

   public Credential createAndFetch(Credential credential) throws IOException {
      String uuid = UUID.randomUUID().toString();
      credential.setId((String)null);
      credential.setDescription(uuid);
      this.create(credential, this.isCrumb());
      Map<String, Credential> credentialsMap = this.list();

      for(Credential item : credentialsMap.values()) {
         if (uuid.equals(item.getDescription())) {
            return item;
         }
      }

      return null;
   }

   public void create(Credential credential, Boolean crumbFlag) throws IOException {
      String url = String.format("%s/%s?", this.baseUrl, "createCredentials");
      this.getClient().postFormJson(url, credential.dataForCreate(), crumbFlag);
   }

   public Map<String, Credential> list() throws IOException {
      String url = String.format("%s?depth=2", this.baseUrl);
      if (this.isVersion1) {
         CredentialResponseV1 response = (CredentialResponseV1)this.getClient().get(url, CredentialResponseV1.class);
         Map<String, Credential> credentials = response.getCredentials();

         for(String crendentialId : credentials.keySet()) {
            ((Credential)credentials.get(crendentialId)).setId(crendentialId);
         }

         return credentials;
      } else {
         CredentialResponse response = (CredentialResponse)this.getClient().get(url, CredentialResponse.class);
         List<Credential> credentials = response.getCredentials();
         Map<String, Credential> credentialMap = new HashMap();

         for(Credential credential : credentials) {
            credentialMap.put(credential.getId(), credential);
         }

         return credentialMap;
      }
   }

   public boolean exists(String credentialId) throws IOException {
      if (credentialId == null) {
         return false;
      } else {
         Map<String, Credential> credentialMap = this.list();

         for(String key : credentialMap.keySet()) {
            if (credentialId.equals(((Credential)credentialMap.get(key)).getId())) {
               return true;
            }
         }

         return false;
      }
   }

   public void update(String credentialId, Credential credential) throws IOException {
      this.update(credentialId, credential, this.isCrumb());
   }

   public void update(String credentialId, Credential credential, Boolean crumbFlag) throws IOException {
      credential.setId(credentialId);
      String url = String.format("%s/%s/%s/%s?", this.baseUrl, "credential", credentialId, "updateSubmit");
      this.getClient().postFormJson(url, credential.dataForUpdate(), crumbFlag);
   }

   public void delete(String credentialId) throws IOException {
      this.delete(credentialId, this.isCrumb());
   }

   public void delete(String credentialId, Boolean crumbFlag) throws IOException {
      String url = String.format("%s/%s/%s/%s?", this.baseUrl, "credential", credentialId, "doDelete");
      this.getClient().postForm(url, new HashMap(), crumbFlag);
   }

   protected String[] getDependencyArray() {
      return new String[0];
   }

   public static class CredentialResponse extends BaseModel {
      private List<Credential> credentials;

      public void setCredentials(List<Credential> credentials) {
         this.credentials = credentials;
      }

      public List<Credential> getCredentials() {
         return this.credentials;
      }
   }

   public static class CredentialResponseV1 extends BaseModel {
      private Map<String, Credential> credentials;

      public Map<String, Credential> getCredentials() {
         return this.credentials;
      }

      public void setCredentials(Map<String, Credential> credentials) {
         this.credentials = credentials;
      }
   }
}
